-- UIBossMonsterInfo
-- Create by huanghr
-- 怪物信息界面

require "game/ui/form/comment/UIComment"

-- UIBossMonsterInfo继承自Layer
UIBossMonsterInfo = class("UIBossMonsterInfo", function()
    return cc.Layer:create();
end);

function UIBossMonsterInfo.create(monsterId, monster, extraPara)
    return UIBossMonsterInfo.new(monsterId, monster, extraPara);
end

local PROP_DESC_COUNT = 3;      -- 特性显示条数

-- 构造函数
function UIBossMonsterInfo:ctor(monsterId, monster, extraPara)
    self:setName("UIBossMonsterInfo");
    self.monsterId = monsterId;
    self.monster = monster;

    self:setLocalZOrder(UIMgr.TOP_MENU_ZORDER + 1);

    -- 初始化
    local node = cc.CSLoader:createNode("layout/monster/MonsterInfo.csb");
    self:addChild(node);
    self.node = node;

    -- 注册返回按钮点击事件
    local btnBack = findChildByName(self.node, "BT/btn_back");
    local function onBackClick(sender, eventType)
        if eventType == ccui.TouchEventType.ended then
            -- 关闭当前界面
            AudioM.playFx("button_return");
            UIMgr.getCurrentScene():removeFormByName("UIBossMonsterInfo");

            if extraPara ~= nil and extraPara["backFunc"] ~= nil then
                extraPara["backFunc"]();
            end
        end
    end

    -- AddTouchEventListener在引导时自动发布TAEGET_CLICK事件
    AddTouchEventListener(btnBack, onBackClick);

    -- AddBackEventHandler在BACK按键点击时，自动触发按钮点击事件
    AddBackEventHandler(self, btnBack, btnBack.touchEventListener);

    TextStyleM.setTextStyle(btnBack, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_BROWN_YELLOW, true);
    if extraPara ~= nil and extraPara["backText"] ~= nil then
        btnBack:setTitleText(getLocStr(extraPara["backText"]));
    else
        btnBack:setTitleText(getLocStr("btn_text_back"));
    end

    -- 怪物名称
    local titleLabel = findChildByName(self.node, "CT/bg/bg/title_label");
    titleLabel:setString(MonsterM.query(monsterId, "name"));
    TextStyleM.setArtWordTitleStyle(titleLabel);

    -- -- 怪物系别
    local styleLabel = findChildByName(self.node, "CT/style");
    TextStyleM.setTextStyle(styleLabel, TextStyleM.TEXT_SIZE_SMALL2, TextStyleM.TEXT_COLOR_BRIGHT_YELLOW, true);
    styleLabel:setString(MonsterM.getStyleName(monsterId));

    -- 根据配置，创建伴生物的模型
    local monsterNode = findChildByName(self.node, "CT/model_node");
    local dbase = MonsterM.query(self.monsterId, "dbase");
    local accompanyId = dbase["accompany_monster_id"];
    if type(accompanyId) == "number" then
        local accompanyDisplay = UIGrid:createAccompanyDisplay(accompanyId);
        monsterNode:addChild(accompanyDisplay);
    end

    -- 怪物模型
    local monsterDisplay = UIGrid:createMonsterDisplay(self.monsterId);
    monsterNode:addChild(monsterDisplay);

    -- BOSS模型需缩小比例
    local scale = 1;

    local dbase = MonsterM.query(self.monsterId, "dbase");
    if dbase["monster_info_scale"] then
        scale = dbase["monster_info_scale"];
    elseif self.monsterId == 900 or self.monsterId == 612 then
        -- TODO 迷宫夹层仙人掌 蘑菇之王
        scale = 1;
    else
        -- 是军团boss
        scale = 1.2;
    end
    monsterNode:setScale(scale);
    -- 属性初始化
    self:initProp();

    -- 注册点击事件
    self:registerTouchEvent();

    -- 注册事件回调
    self:registerEventCallback();

    -- 检查评论数量
    self:checkCommentCount();

    -- 适配
    self:resize();

    self:initPropPanel();
end

-- 注册事件回调事件
function UIBossMonsterInfo:registerEventCallback()
    -- 关注评论数量更新
    EventMgr.register("UIBossMonsterInfo", event.UPDATE_COMMENT_COUNT, function(para)
        self:checkCommentCount(para);
    end);

    -- 界面析构后，需要清理下
    self:registerScriptHandler(function(ev)
        if ev == "exit" then
            EventMgr.removeAll("UIBossMonsterInfo");
            if UIDungeonMgr:getCurLevel() then
                UIDungeonMgr:getCurLevel():showTop();
            end
        elseif ev == "enter" then
            if UIDungeonMgr:getCurLevel() then
                UIDungeonMgr:getCurLevel():hideTop();
            end
        end
    end);
end

-- 检查评论数量
function UIBossMonsterInfo:checkCommentCount(para)
    -- 评论按钮
    local btnComment = findChildByName(self.node, "BT/btn_comment");
    local commentLabel = findChildByName(btnComment, "comment_label");
    local hintNode = findChildByName(btnComment, "hint");
    local commentType = "monster_" .. tostring(MonsterM.query(self.monsterId, "base_class_id"));

    if para and para.commentType ~= commentType then
        return;
    end

    local count = CommentM.getCommentCount(commentType);
    local kerning = 0;
    if getLang() == "zh" or getLang == "tw" then
        kerning = 4;
    end
    TextStyleM.setTextStyle(commentLabel, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_BROWN_YELLOW, true, kerning, nil, nil, nil, nil, true);
    btnComment:setTitleText("");
    commentLabel:setString(string.format(getLocStr("btn_text_comment_num"), count));
end

-- 注册点击事件
function UIBossMonsterInfo:registerTouchEvent()
    -- 评论界面参数
    local data = {
        ["title"] = MonsterM.query(self.monsterId, "name"),
        ["type"] = "monster_" .. tostring(MonsterM.query(self.monsterId, "base_class_id")),
    }

    local btnComment =  findChildByName(self.node, "BT/btn_comment");
    btnComment:setVisible(true);
    local function onCommentClick(sender, eventType)
        if eventType ==  ccui.TouchEventType.ended then
            -- 打开评论界面
            AudioM.playFx("button_click");
            UIMgr.getCurrentScene():removeFormByName("UIComment");
            local uiComment = UIComment.create(data);
            UIMgr.getCurrentScene():addForm(uiComment);
        end
    end
    btnComment:addTouchEventListener(onCommentClick);
    TextStyleM.setTextStyle(btnComment, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_BROWN_YELLOW, true);
    btnComment:setTitleText(getLocStr("btn_text_new_comment"));

    -- 获取评论数量
    Operation.cmd_get_comment_counts(data.type);
end

-- 属性初始化
function UIBossMonsterInfo:initProp()
    local names = {"attack", "hp", "dodge", "accuracy"};
    local values = {self.monster:getAttack(), self.monster:getMaxHp(), self.monster:getDodge(), self.monster:getAccuracy()};

    local rightPart = findChildByName(self.node, "CT/bg/right_part");
    for i = 1, #names do
        local nameLabel = findChildByName(rightPart, names[i] .. "_node/name");
        TextStyleM.setTextStyle(nameLabel, TextStyleM.TEXT_SIZE_SMALL2, TextStyleM.TEXT_COLOR_BEIGE, false, -1);
        nameLabel:setString(getLocStr(names[i]));

        local valueLabel = findChildByName(rightPart, names[i] .. "_node/value");
        local showNum;
        -- 血量和攻击限制
        if i == 2 and values[i] > 9999 then
            showNum = "????";
        elseif i == 1 and values[i] > 999 then
            showNum = "???";
        else
            showNum = values[i];
        end

        -- 闪避和命中要加百分号
        showNum = tostring(showNum);
        if  "dodge" == names[i] or "accuracy" == names[i] then
            showNum = showNum .. "%";
        end
        TextStyleM.setTextStyle(valueLabel, TextStyleM.TEXT_SIZE_SMALL2, TextStyleM.TEXT_COLOR_BEIGE, false, -1);
        valueLabel:setString(showNum);
    end
end

-- 特性描述的panel初始化
function UIBossMonsterInfo:initPropPanel()
    --
    local scrollview = findChildByName(self.node, "CT/scrollview");
    scrollview:removeAllChildren();

    local itemNode = cc.CSLoader:createNode("layout/monster/MonsterInfoNode.csb");
    local widget = replaceNodeWithWidget(itemNode);

    -- 左边距
    local leftMargin = 1;

    -- 行间距
    local gap = 10;

    local startHeight = 10;

    -- 怪物描述
    local descInfoList = MonsterM.query(self.monsterId, "desc");

    -- 判断skill下的prop是否还有效
    local descInfo;
    local propList = self.monster.dbase:queryTemp("prop", "skill", false);
    local isAllForbidClear = true;
    if propList then
        for _, prop in pairs(propList) do
            if PropM.query(prop[1], "forbid_clear") ~= 1 then
                isAllForbidClear = false;
            end
        end
    end

    if isAllForbidClear then
        -- 当skill中只剩下forbid_clear=1的prop时，怪物属性也只显示forbid_clear=1的描述
        descInfo = {};
        for _, desc in pairs(descInfoList) do
            if desc.forbid_clear == 1 then
                table.insert(descInfo, desc);
            end
        end
    else
        local dbase = MonsterM.query(self.monsterId, "dbase");
        if dbase["monster_desc_formula"] then
            -- 有公式
            descInfo = FormulaM.invoke(dbase["monster_desc_formula"], ME.user, self.monsterId);
        else
            descInfo = table.deepcopy(descInfoList);
        end
    end

    -- 增益和减益
    if self.monster then
        local buffList = FormulaM.invoke("GET_MONSTER_BUFF", self.monster);
        local deBuffList = FormulaM.invoke("GET_MONSTER_DEBUFF", self.monster);
        local combatStatus = self.monster.dbase:query("combat_status", {});

        local function handleProp(list, color)
            local handled = {};
            for _, prop in pairs(list) do
                repeat
                    if FormulaM.invoke("IS_UNSHOWN_PROP", prop) then
                        break;
                    end

                    if type(handled[prop[1]]) == "table" and handled[prop[1]][prop[2]] then
                        break;
                    end

                    local title = PropM.getPropAlias(prop[1], prop);
                    if title == "" then
                        title = "UNKNOWN TITLE";
                    end

                    local desc = PropM.getPropDesc(prop);
                    local tipStr = "";

                    if prop[4] > 0 then
                        local restRound = prop[4] - CombatM.getRound();
                        if restRound > 0 then
                            tipStr = string.format(getLocStr("monster_buff_tip"), restRound);
                        end
                    end

                    title = title .. tipStr;

                    table.insert(descInfo, {name = title, desc = desc, bgColor = color });
                    handled[prop[1]] = {};
                    handled[prop[1]][prop[2]] = true;
                until true;
            end
        end

        -- 2. 状态类的
        local function handleStatus(combatStatus, statusType, color)
            for status, condition in pairs(combatStatus) do
                repeat
                    if CombatStatusM.query(status, "type") ~= statusType then
                        break;
                    end

                    -- 配置了不显示
                    local dbase = MonsterM.query(self.monster.classId, "dbase");
                    local alias = CombatStatusM.query(status, "alias") or "";
                    if dbase["hide_cs_tip"] and table.indexOf(dbase["hide_cs_tip"], alias) >= 0 then
                        break;
                    end

                    local title = CombatStatusM.getStatusName(self.monster, status);

                    local desc = CombatStatusM.getStatusDesc(self.monster, status);
                    local tipStr = "";

                    if condition["end_round"] > 0 then
                        local restRound = condition["end_round"] - CombatM.getRound();
                        if restRound > 0 then
                            tipStr = string.format(getLocStr("monster_buff_tip"), restRound);
                        end
                    end

                    title = title .. tipStr;

                    table.insert(descInfo, {name = title, desc = desc, bgColor = color });
                until true;
            end
        end

        -- 光环
        local function handleAssistProp()
            local assistProp = table.add(self.monster.dbase:queryTemp("assist_map", {}), self.monster.dbase:queryTemp("assist_summon_map", {}));
            assistProp = table.add(assistProp, self.monster.dbase:queryTemp("assist_grid_map", {}));
            for assistId, count in pairs(assistProp) do
                repeat
                    local dbase = AssistMonsterM.query(assistId, "dbase") or {};
                    if 1 == dbase.revive_limit and self.monster.hasRevived then
                        -- 已经复活过了
                        break;
                    end

                    -- 不显示
                    if 1 == dbase["not_show"] then
                        break;
                    end

                    local color = AssistMonsterM.query(assistId, "color");
                    -- 默认是绿色的
                    if not color or #color <= 0 then
                        color = "green";
                    end

                    local desc = AssistMonsterM.getAssistDesc(assistId, count);
                    local title = AssistMonsterM.query(assistId, "name");

                    table.insert(descInfo, {name = title, desc = desc, bgColor = color });

                until true;
            end
        end

        -- 增益
        handleStatus(combatStatus, COM_STATUS_BUFF, "red");
        handleProp(buffList, "red");

        -- 减益
        handleProp(deBuffList, "red");
        handleStatus(combatStatus, COM_STATUS_DEBUFF, "red");
        handleStatus(combatStatus, COM_STATUS_DAMAGE, "red");
        handleStatus(combatStatus, COM_STATUS_SPECIAL, "red");

        -- 光环属性
        handleAssistProp();
    end

    local propBg;
    local propNameLabel;
    local propDescLabel;
    local totalHeight;
    local n = 1;
    local curHeight = 20;
    local ret = {};

    local itemName = "prop_";
    local count = math.max(PROP_DESC_COUNT, #descInfo);
    local showNum = 0;

    for i = 1, count do
        if descInfo[i] ~= nil then
            -- 找到描述了，设置描述内容
            local child = widget:clone();
            child:setName(itemName .. n);

            propNameLabel = findChildByName(child, "prop_name");
            propDescLabel = findChildByName(child, "prop_desc");
            propBg        = findChildByName(child, "prop_bg");

            -- 设置文本风格
            TextStyleM.setTextStyle(propNameLabel, TextStyleM.TEXT_SIZE_SMALL2, TextStyleM.TEXT_COLOR_BEIGE, false);
            TextStyleM.setTextStyle(propDescLabel, TextStyleM.TEXT_SIZE_SMALL2, TextStyleM.TEXT_COLOR_BEIGE);

            local nameText = getMonsterLocStr(descInfo[i].name);
            local descText = getMonsterLocStr(descInfo[i].desc);

            -- 需要动态显示数值的怪物描述
            if descInfo[i].prop_id then
                descText = FormulaM.invoke("GET_SPECIAL_MONSTER_DESC", self.monster, descInfo[i].prop_id, descText);
            end

            -- 如果已经失效了，显示"(已失效)"
            if descInfo[i].skill_id then
                descText = FormulaM.invoke("GET_VARY_DESC", self.monster, descText, descInfo[i].skill_id);

                local invalidSkills = self.monster.dbase:query("invalid_skills") or {};

                if table.indexOf(invalidSkills, descInfo[i].skill_id) > 0 then
                    local invalidText = string.format(getLocStr("invalid_skill_desc"), getLocStr("invalid_skill_text"));
                    local skillDbase = SkillM.query(descInfo[i].skill_id, "dbase");
                    if skillDbase["invalid_status"] then
                        invalidText = string.format(getLocStr("invalid_skill_desc"), skillDbase["invalid_status"]);
                    end
                    nameText = spliceLocStr(nameText, invalidText);
                end
            end

            propNameLabel = applyString(propNameLabel, nameText);

            if not descText then
                child:setVisible(false);
            else
                table.insert(ret, curHeight)

                descText = extractString(descText);
                propDescLabel = applyString(propDescLabel, descText);

                showNum = showNum + 1;

                -- 文本可见
                propNameLabel:setVisible(true);
                propDescLabel:setVisible(true);

                -- 获得高的值
                local nameHeight = propNameLabel:getContentSize().height;
                local descHeight = propDescLabel:getContentSize().height;

                local propHeight = nameHeight + descHeight + 36;

                curHeight = curHeight + propHeight + 10;

                if descInfo[i].bgColor ~= nil then
                    -- local colorPic = "point_" .. descInfo[i].bgColor;
                    local picRootPath = getTitleBgIconPath("point_red");
                    propBg:loadTexture(picRootPath);
                end

                propBg:setContentSize(propBg:getContentSize().width, propHeight);

                n = n + 1;

                scrollview:addChild(child);
            end
        end
    end

    -- 重新调整位置
    --计算总高度
    local totalHeight = math.max(curHeight, scrollview:getInnerContainerSize().height);
    startHeight = totalHeight;

    scrollview:setInnerContainerSize(cc.size(scrollview:getInnerContainerSize().width, totalHeight));

    for j = 1, showNum do
        local child = findChildByName(scrollview, "prop_" .. j);
        local pos = ret[j];
        child:setPosition(cc.p(255, startHeight - pos));
    end
end

-- 适配
function UIBossMonsterInfo:resize()
    local node = self.node;

    -- bg居中显示并充满整个屏幕
    AlignM.fitToScreen(node, "bg");

    -- CT居中并缩放至合适大小
    AlignM.alignToCenter(node, "CT");

    -- BT置于底部并缩放至合适大小
    AlignM.alignToBottomCenter(node, "BT");
end


